package com.yhos.platform.oopston.service.biz;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yhos.platform.oopston.base.config.OopstonConfig;
import com.yhos.platform.oopston.base.constants.BaseOperatorConstant;
import com.yhos.platform.oopston.base.constants.CommonConstants;
import com.yhos.platform.oopston.base.enums.ChannelTypeEnum;
import com.yhos.platform.oopston.base.enums.ShippingMethodEnum;
import com.yhos.platform.oopston.base.enums.TrueFalseEnum;
import com.yhos.platform.oopston.base.enums.YesNoEnum;
import com.yhos.platform.oopston.core.exception.BusinessException;
import com.yhos.platform.oopston.core.utils.*;
import com.yhos.platform.oopston.mapper.entity.OopstonOrder;
import com.yhos.platform.oopston.mapper.entity.OopstonOrderExtraService;
import com.yhos.platform.oopston.mapper.entity.ShunfengOrderTrackingInfo;
import com.yhos.platform.oopston.mapper.mapper.OopstonOrderMapper;
import com.yhos.platform.oopston.mapper.mapper.ShunfengOrderTrackingInfoMapper;
import com.yhos.platform.oopston.mapper.model.RequestBaseModel;
import com.yhos.platform.oopston.mapper.model.fish.*;
import com.yhos.platform.oopston.mapper.model.oopston.*;
import com.yhos.platform.oopston.mapper.model.zhongtong.*;
import com.yhos.platform.oopston.service.biz.sensitiveword.SensitiveWordFilter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * Created by Administrator on 2020/4/19.
 */
@Service
public class OrderBiz {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private OopstonConfig oopstonConfig;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private MessageSourceUtils messageSourceUtils;

    @Autowired
    private OopstonOrderMapper oopstonOrderMapper;

    @Autowired
    private OrderLabelBiz orderLabelBiz;

    @Autowired
    private ShunfengOrderTrackingInfoMapper trackingInfoMapper;

    @Autowired
    private OrderOperateBiz orderOperateBiz;

    @Autowired
    private SensitiveWordFilter sensitiveWordFilter;

    private ObjectMapper objectMapper = JacksonUtils.getInstance();

    private static final String OOPSTON_ORDER_CREATE_URL = "http://my.megawms.com/PubApi/AddOrder.aspx";

    private static final String OOPSTON_ORDER_CANCEL_URL = "http://my.megawms.com/PubApi/InvalidOrder.aspx";

    private static final String OOPSTON_GET_TRACK_URL = "http://my.megawms.com/PubApi/GetTrack.aspx";

    private static final String ZHONG_TONG_REQUEST_URL = "http://139.196.166.242:8026/webservice/PublicService.asmx/ServiceInterfaceUTF8";

    private static final String ZHONG_TONG_ORDER_CREATE_METHOD = "createorder";

    private static final String ZHONG_TONG_ORDER_DELETE_METHOD = "removeorder";

    private static final String ZHONG_TONG_TRACK_GET_METHOD = "gettrack";

    private static final String ZHONG_TONG_TAG_GET_METHOD = "getnewlabel";

    //开始处理发送Tracking info
   // private static final String FLY_FISH_TRACK_PUSH_URL = "http://st-t.vova.com.hk/v2/trackings/webhook/singleTrack"; //testing

     private static final String FLY_FISH_TRACK_PUSH_URL = "https://vvst.vova.com.hk/v2/trackings/webhook/singleTrack"; //product

    private static final String FISH_STATUS ="success";

    /**
     * 创建OPPO订单
     *
     * @param requestApiModel
     */
    @Transactional
    public OrderCreateResponseApiModel createOrder(OrderCreateRequestApiModel requestApiModel) {
        OrderCreateResponseApiModel responseApiModel = new OrderCreateResponseApiModel();
        List<OopstonOrder> oopstonOrderList = oopstonOrderMapper.selectList(new EntityWrapper<OopstonOrder>().eq("Delete_Yn", YesNoEnum.NO.getKey())
                .eq("Cancel_Status", YesNoEnum.NO.getKey())
                .eq("Order_Ref_No",requestApiModel.getReferenceNo())
                .in("Channel_Type", Arrays.asList(ChannelTypeEnum.FBA_USOUG.getKey(), ChannelTypeEnum.FBA_USOFG.getKey(), ChannelTypeEnum.FBA_USAFG.getKey(), ChannelTypeEnum.FBA_USAUG.getKey()))
                .isNotNull("Response_Order_ID"));

        if (ListUtils.isNotEmpty(oopstonOrderList)) {
            responseApiModel.setOrderId(String.valueOf(oopstonOrderList.get(0).getId()));
            responseApiModel.setReferenceNo(oopstonOrderList.get(0).getOrderRefNo());
            responseApiModel.setTrackNumber(oopstonOrderList.get(0).getResponseTrackNumber());
            return responseApiModel;
        }

        OopstonOrder order = orderLabelBiz.createOrderInfo(requestApiModel);

        //封装接口参数
        OrderCreateRemoteRequest remoteRequest = buildCreateOrderRemoteRequest(requestApiModel);
        //封装接口调用认证参数
        this.setPackageChannelInfo(remoteRequest, order.getBaseChannelInfoId());

        responseApiModel = this.request(OOPSTON_ORDER_CREATE_URL, remoteRequest, ParameterizedTypeReference.forType(OrderCreateResponseApiModel.class));
        if (responseApiModel != null) {
            //如果下游处理失败，将失败原因往外抛
            if (TrueFalseEnum.FALSE.getValue().equalsIgnoreCase(responseApiModel.getSuccess())) {
                //下游返回空处理
                throw new BusinessException(responseApiModel.getMessage(),
                        BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED);
            } else {
                orderLabelBiz.updateResponse(order.getId(), responseApiModel);
            }
        } else {
            //下游返回空处理
            throw new BusinessException(messageSourceUtils.getMessage(
                    BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED),
                    BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED);
        }
        responseApiModel.setOrderId(String.valueOf(order.getId()));
        responseApiModel.setReferenceNo(requestApiModel.getReferenceNo());
        return responseApiModel;
    }

    /**
     * 取消订单
     */
    @Transactional
    public OrderCancelResponseApiModel cancelOrder(OrderCancelRequestApiModel requestApiModel) {

        OopstonOrder oopstonOrder = oopstonOrderMapper.selectById(requestApiModel.getOrderId());
        if (oopstonOrder == null) {
            //根据跟踪号没有获取到订单，需要抛异常
            throw new BusinessException(messageSourceUtils.getMessage(
                    BaseOperatorConstant.ORDER_NO_EXIST),
                    BaseOperatorConstant.ORDER_NO_EXIST);
        }
        if(YesNoEnum.YES.getKey().equals(oopstonOrder.getCancelStatus())){
            //订单已取消
            throw new BusinessException("订单已取消");
        }

        OrderCancelResponseApiModel responseApiModel = new OrderCancelResponseApiModel();
        if (Arrays.asList(ChannelTypeEnum.FBA_USOUG.getKey(), ChannelTypeEnum.FBA_USOFG.getKey(), ChannelTypeEnum.FBA_USAFG.getKey(), ChannelTypeEnum.FBA_USAUG.getKey())
                .contains(oopstonOrder.getChannelType())) {
            //封装接口调用认证参数
            this.setPackageChannelInfo(requestApiModel, oopstonOrder.getBaseChannelInfoId());
            requestApiModel.setTrackNumber(oopstonOrder.getOrderRefNo());
            responseApiModel = this.request(OOPSTON_ORDER_CANCEL_URL, requestApiModel, new ParameterizedTypeReference<OrderCancelResponseApiModel>() {
            });
            if (responseApiModel != null) {
                //如果下游处理失败，将失败原因往外抛
                if (TrueFalseEnum.FALSE.getValue().equalsIgnoreCase(responseApiModel.getSuccess())) {
                    //下游返回空处理
                    throw new BusinessException(responseApiModel.getMessage(),
                            BaseOperatorConstant.ORDER_CANCEL_OOPSTON_REQUEST_FAILED);
                } else {
                    //更新订单取消状态
                    orderOperateBiz.updateOrderCancelStatus(oopstonOrder.getId());
                }
            } else {
                //下游返回空处理
                throw new BusinessException(messageSourceUtils.getMessage(
                        BaseOperatorConstant.ORDER_CANCEL_OOPSTON_REQUEST_FAILED),
                        BaseOperatorConstant.ORDER_CANCEL_OOPSTON_REQUEST_FAILED);
            }
        } else if (Arrays.asList(ChannelTypeEnum.USUSPS_F.getKey(), ChannelTypeEnum.USUSPS_P.getKey(), ChannelTypeEnum.USDHL_E.getKey(), ChannelTypeEnum.Fedex_smart_post.getKey())
                .contains(oopstonOrder.getChannelType())) {
            ZhongTongOrderDeleteRemoteRequest remoteRequest = new ZhongTongOrderDeleteRemoteRequest();
            remoteRequest.setReferenceNo(oopstonOrder.getOrderRefNo());
            ZhongTongBaseRemoteResponse remoteResponse = this.formRequest(ZHONG_TONG_REQUEST_URL, ZHONG_TONG_ORDER_DELETE_METHOD, remoteRequest,
                    ParameterizedTypeReference.forType(ZhongTongBaseRemoteResponse.class));

            if (remoteResponse != null) {
                //如果下游处理失败，将失败原因往外抛
                if (CommonConstants.STRING_ZERO.equalsIgnoreCase(remoteResponse.getSuccess())) {
                    //下游返回空处理
                    throw new BusinessException(remoteResponse.getCnmessage(),
                            BaseOperatorConstant.ORDER_CANCEL_OOPSTON_REQUEST_FAILED);
                } else {
                    //更新订单取消状态
                    orderOperateBiz.updateOrderCancelStatus(oopstonOrder.getId());
                }
            } else {
                //下游返回空处理
                throw new BusinessException(messageSourceUtils.getMessage(
                        BaseOperatorConstant.ORDER_CANCEL_OOPSTON_REQUEST_FAILED),
                        BaseOperatorConstant.ORDER_CANCEL_OOPSTON_REQUEST_FAILED);
            }
        } else {
            //根据跟踪号没有获取到订单，需要抛异常
            throw new BusinessException(messageSourceUtils.getMessage(
                    BaseOperatorConstant.ORDER_NO_EXIST),
                    BaseOperatorConstant.ORDER_NO_EXIST);
        }
        responseApiModel.setOrderId(String.valueOf(oopstonOrder.getId()));
        responseApiModel.setReferenceNo(oopstonOrder.getOrderRefNo());
        responseApiModel.setTrackNumber(oopstonOrder.getResponseTrackNumber());
        return responseApiModel;
    }

    public OrderGetTrackDetailResponseBatchApiModel getOrderTrackBatchSave() {
        OrderGetTrackDetailResponseBatchApiModel responseApiModel = new OrderGetTrackDetailResponseBatchApiModel();
        List<OrderGetTrackResponseApiModel> trackDetailList = new ArrayList<>();
        OrderGetTrackResponseApiModel responseApiModelDetail = new OrderGetTrackResponseApiModel();
        List<OopstonOrder> oopstonOrderList = oopstonOrderMapper.selectList(new EntityWrapper<OopstonOrder>().eq("Delete_Yn", YesNoEnum.NO.getKey())
                .eq("Order_Status", YesNoEnum.NO.getKey())
                .isNotNull("Response_Order_ID"));
        if (ListUtils.isNotEmpty(oopstonOrderList)) {
            for (OopstonOrder order : oopstonOrderList) {
                responseApiModelDetail = getOrderTrackInfo(order.getId());
                trackDetailList.add(responseApiModelDetail);
            }
            responseApiModel.setData(trackDetailList);
        }
        return responseApiModel;
    }

    public OrderGetTrackResponseApiModel getOrderTrackInfo(Long orderId) {
        String ls_tracking_time = null;
        String ls_tracking_info = null;
        String ls_tracking_no = null;
        String ls_tracking_weight = null;
        OrderGetTrackResponseApiModel responseApiModel = new OrderGetTrackResponseApiModel();
        OopstonOrder order = oopstonOrderMapper.selectById(orderId);
        if (order != null) {
            if (Arrays.asList(ChannelTypeEnum.FBA_USOUG.getKey(), ChannelTypeEnum.FBA_USOFG.getKey(), ChannelTypeEnum.FBA_USAFG.getKey(), ChannelTypeEnum.FBA_USAUG.getKey())
                    .contains(order.getChannelType())) {
                GetTrackRemoteRequest remoteRequest = new GetTrackRemoteRequest();
                if (oopstonConfig.getSmallPackChannelId().equals(order.getBaseChannelInfoId())) {
                    remoteRequest.setKey(oopstonConfig.getSmallPackApiKey());
                } else if (oopstonConfig.getBigPackChannelId().equals(order.getBaseChannelInfoId())) {
                    remoteRequest.setKey(oopstonConfig.getBigPackApiKey());
                }
                List<GetTrackDetailRemoteRequest> trackingNos = new ArrayList<>();
                GetTrackDetailRemoteRequest remoteDetailRequest = new GetTrackDetailRemoteRequest();
                remoteDetailRequest.setTrackingNo(order.getResponseTrackNumber());
                trackingNos.add(remoteDetailRequest);
                remoteRequest.setTrackingNos(trackingNos);
                GetTrackRemoteResponse remoteResponse = this.request(OOPSTON_GET_TRACK_URL, remoteRequest, ParameterizedTypeReference.forType(GetTrackRemoteResponse.class));
                if (remoteResponse != null) {
                    //如果下游处理失败，将失败原因往外抛
                    if (TrueFalseEnum.FALSE.getValue().equalsIgnoreCase(remoteResponse.getSuccess())) {
                        //下游返回空处理
                        throw new BusinessException(remoteResponse.getMessage(),
                                BaseOperatorConstant.ORDER_GET_TRACK_REQUEST_FAILED);
                    } else {
                        responseApiModel.setOrderId(order.getId());
                        responseApiModel.setTrackNumber(order.getResponseTrackNumber());
                        if (ListUtils.isNotEmpty(remoteResponse.getTrackingNos())) {
                            for (OrderGetTrackDetailRemoteResponse trackNo : remoteResponse.getTrackingNos()) {
                                responseApiModel.setTrackNumber(trackNo.getTrackingNo());
                                responseApiModel.setCountry(trackNo.getCountry());
                                responseApiModel.setStatus(trackNo.getStatus());
                                List<OrderGetTrackDetailResponseApiModel> trackDetailList = new ArrayList<>();
                                if (ListUtils.isNotEmpty(trackNo.getTrack())) {
                                    for (OrderGetTrackDetailsRemoteResponse track : trackNo.getTrack()) {
                                        OrderGetTrackDetailResponseApiModel trackDetail = new OrderGetTrackDetailResponseApiModel();
                                        trackDetail.setOccurTime(track.getOccurTime());
                                        trackDetail.setDescription(track.getDescriptionCn());
                                        trackDetailList.add(trackDetail);
                                    }
                                }
                                responseApiModel.setTrack(trackDetailList);
                            }
                        }
                    }
                } else {
                    //下游返回空处理
                    throw new BusinessException(messageSourceUtils.getMessage(
                            BaseOperatorConstant.ORDER_GET_TRACK_REQUEST_FAILED),
                            BaseOperatorConstant.ORDER_GET_TRACK_REQUEST_FAILED);
                }
            } else if (Arrays.asList(ChannelTypeEnum.USUSPS_F.getKey(), ChannelTypeEnum.USUSPS_P.getKey(), ChannelTypeEnum.USDHL_E.getKey(), ChannelTypeEnum.Fedex_smart_post.getKey())
                    .contains(order.getChannelType())) {
                ZhongTongTrackingRemoteRequest remoteRequest = new ZhongTongTrackingRemoteRequest();
                remoteRequest.setTrackingNumber(order.getResponseTrackNumber());
                ZhongTongTrackingRemoteResponse remoteResponse = this.formRequest(ZHONG_TONG_REQUEST_URL, ZHONG_TONG_TRACK_GET_METHOD, remoteRequest,
                        ParameterizedTypeReference.forType(ZhongTongTrackingRemoteResponse.class));
                if (remoteResponse != null) {
                    //如果下游处理失败，将失败原因往外抛
                    if (CommonConstants.STRING_ZERO.equalsIgnoreCase(remoteResponse.getSuccess())) {
                        //下游返回空处理
//                        throw new BusinessException(remoteResponse.getCnmessage(),TODO
//                                BaseOperatorConstant.ORDER_GET_TRACK_REQUEST_FAILED);
                    } else {
                        responseApiModel.setOrderId(orderId);
                        responseApiModel.setTrackNumber(order.getResponseTrackNumber());
                        if (ListUtils.isNotEmpty(remoteResponse.getData())) {
                            for (ZhongTongTrackingDetailRemoteResponse trackNo : remoteResponse.getData()) {
                                responseApiModel.setTrackNumber(trackNo.getServerHawbcode());
                                responseApiModel.setCountry(trackNo.getDestinationCountry());
                                responseApiModel.setStatus(trackNo.getTrackStatusName());
                                List<OrderGetTrackDetailResponseApiModel> trackDetailList = new ArrayList<>();
                                if (ListUtils.isNotEmpty(trackNo.getDetails())) {
                                    for (ZhongTongTrackingDetailsRemoteResponse track : trackNo.getDetails()) {
                                        ShunfengOrderTrackingInfo trackingInfoNew = new ShunfengOrderTrackingInfo();
                                        ls_tracking_time = null;
                                        ls_tracking_info = null;
                                        ls_tracking_no = null;
                                        ls_tracking_weight = null;
                                        OrderGetTrackDetailResponseApiModel trackDetail = new OrderGetTrackDetailResponseApiModel();
                                        trackDetail.setOccurTime(track.getTrackOccurDate());
                                        trackDetail.setDescription(track.getTrackDescription());
                                        trackDetailList.add(trackDetail);
                                        ls_tracking_time = track.getTrackOccurDate().toString();
                                        ls_tracking_info = track.getTrackDescription();
                                        trackingInfoNew.setOrderId(order.getId());
                                        trackingInfoNew.setTrackingNo(order.getResponseTrackNumber());
                                        trackingInfoNew.setTotalWeight(order.getTotalWeight().toString());
                                        trackingInfoNew.setMessage(ls_tracking_info);
                                        trackingInfoNew.setSendTime(ls_tracking_time);
                                        orderLabelBiz.saveTrackInfo(trackingInfoNew);
                                        //如果是送达的最后状态，需要更新Order状态，下次不用再次发送Tracking信息
                                        String ls_tracking_status = autoCalculateStatus(ls_tracking_info);
                                        if (ls_tracking_info.equals("DELIVERED")) {orderLabelBiz.updateZhongTongTrackStatus(order.getId());}
                                    }
                                }
                                responseApiModel.setTrack(trackDetailList);
                            }
                        }
                    }
                } else {
                    //下游返回空处理
//                    throw new BusinessException(messageSourceUtils.getMessage(
//                            BaseOperatorConstant.ORDER_GET_TRACK_REQUEST_FAILED),
//                            BaseOperatorConstant.ORDER_GET_TRACK_REQUEST_FAILED);
                }
            }
        } else {
//            throw new BusinessException("未找到订单");
        }

        return responseApiModel;
    }

    public OrderGetTrackResponseApiModel getOrderTrack(Long orderId) {
        String ls_tracking_time = null;
        String ls_tracking_info = null;
        String ls_tracking_no = null;
        String ls_tracking_weight = null;
        OrderGetTrackResponseApiModel responseApiModel = new OrderGetTrackResponseApiModel();
        OopstonOrder order = oopstonOrderMapper.selectById(orderId);
        if (order != null) {
            if (Arrays.asList(ChannelTypeEnum.FBA_USOUG.getKey(), ChannelTypeEnum.FBA_USOFG.getKey(), ChannelTypeEnum.FBA_USAFG.getKey(), ChannelTypeEnum.FBA_USAUG.getKey())
                    .contains(order.getChannelType())) {
                GetTrackRemoteRequest remoteRequest = new GetTrackRemoteRequest();
                if (oopstonConfig.getSmallPackChannelId().equals(order.getBaseChannelInfoId())) {
                    remoteRequest.setKey(oopstonConfig.getSmallPackApiKey());
                } else if (oopstonConfig.getBigPackChannelId().equals(order.getBaseChannelInfoId())) {
                    remoteRequest.setKey(oopstonConfig.getBigPackApiKey());
                }
                List<GetTrackDetailRemoteRequest> trackingNos = new ArrayList<>();
                GetTrackDetailRemoteRequest remoteDetailRequest = new GetTrackDetailRemoteRequest();
                remoteDetailRequest.setTrackingNo(order.getResponseTrackNumber());
                trackingNos.add(remoteDetailRequest);
                remoteRequest.setTrackingNos(trackingNos);
                GetTrackRemoteResponse remoteResponse = this.request(OOPSTON_GET_TRACK_URL, remoteRequest, ParameterizedTypeReference.forType(GetTrackRemoteResponse.class));
                if (remoteResponse != null) {
                    //如果下游处理失败，将失败原因往外抛
                    if (TrueFalseEnum.FALSE.getValue().equalsIgnoreCase(remoteResponse.getSuccess())) {
                        //下游返回空处理
                        throw new BusinessException(remoteResponse.getMessage(),
                                BaseOperatorConstant.ORDER_GET_TRACK_REQUEST_FAILED);
                    } else {
                        responseApiModel.setOrderId(order.getId());
                        responseApiModel.setTrackNumber(order.getResponseTrackNumber());
                        if (ListUtils.isNotEmpty(remoteResponse.getTrackingNos())) {
                            for (OrderGetTrackDetailRemoteResponse trackNo : remoteResponse.getTrackingNos()) {
                                responseApiModel.setTrackNumber(trackNo.getTrackingNo());
                                responseApiModel.setCountry(trackNo.getCountry());
                                responseApiModel.setStatus(trackNo.getStatus());
                                List<OrderGetTrackDetailResponseApiModel> trackDetailList = new ArrayList<>();
                                if (ListUtils.isNotEmpty(trackNo.getTrack())) {
                                    for (OrderGetTrackDetailsRemoteResponse track : trackNo.getTrack()) {
                                        OrderGetTrackDetailResponseApiModel trackDetail = new OrderGetTrackDetailResponseApiModel();
                                        trackDetail.setOccurTime(track.getOccurTime());
                                        trackDetail.setDescription(track.getDescriptionCn());
                                        trackDetailList.add(trackDetail);
                                    }
                                }
                                responseApiModel.setTrack(trackDetailList);
                            }
                        }
                    }
                } else {
                    //下游返回空处理
                    throw new BusinessException(messageSourceUtils.getMessage(
                            BaseOperatorConstant.ORDER_GET_TRACK_REQUEST_FAILED),
                            BaseOperatorConstant.ORDER_GET_TRACK_REQUEST_FAILED);
                }
            } else if (Arrays.asList(ChannelTypeEnum.USUSPS_F.getKey(), ChannelTypeEnum.USUSPS_P.getKey(), ChannelTypeEnum.USDHL_E.getKey(), ChannelTypeEnum.Fedex_smart_post.getKey())
                    .contains(order.getChannelType())) {
                ZhongTongTrackingRemoteRequest remoteRequest = new ZhongTongTrackingRemoteRequest();
                remoteRequest.setTrackingNumber(order.getResponseTrackNumber());
                ZhongTongTrackingRemoteResponse remoteResponse = this.formRequest(ZHONG_TONG_REQUEST_URL, ZHONG_TONG_TRACK_GET_METHOD, remoteRequest,
                        ParameterizedTypeReference.forType(ZhongTongTrackingRemoteResponse.class));
                if (remoteResponse != null) {
                    //如果下游处理失败，将失败原因往外抛
                    if (CommonConstants.STRING_ZERO.equalsIgnoreCase(remoteResponse.getSuccess())) {
                        //下游返回空处理
                        throw new BusinessException(remoteResponse.getCnmessage(),
                                BaseOperatorConstant.ORDER_GET_TRACK_REQUEST_FAILED);
                    } else {
                        responseApiModel.setOrderId(orderId);
                        responseApiModel.setTrackNumber(order.getResponseTrackNumber());
                        if (ListUtils.isNotEmpty(remoteResponse.getData())) {
                            for (ZhongTongTrackingDetailRemoteResponse trackNo : remoteResponse.getData()) {
                                responseApiModel.setTrackNumber(trackNo.getServerHawbcode());
                                responseApiModel.setCountry(trackNo.getDestinationCountry());
                                responseApiModel.setStatus(trackNo.getTrackStatusName());
                                List<OrderGetTrackDetailResponseApiModel> trackDetailList = new ArrayList<>();
                                if (ListUtils.isNotEmpty(trackNo.getDetails())) {
                                    for (ZhongTongTrackingDetailsRemoteResponse track : trackNo.getDetails()) {
                                        ShunfengOrderTrackingInfo trackingInfoNew = new ShunfengOrderTrackingInfo();
                                        ls_tracking_time = null;
                                        ls_tracking_info = null;
                                        ls_tracking_no = null;
                                        ls_tracking_weight = null;
                                        OrderGetTrackDetailResponseApiModel trackDetail = new OrderGetTrackDetailResponseApiModel();
                                        trackDetail.setOccurTime(track.getTrackOccurDate());
                                        trackDetail.setDescription(track.getTrackDescription());
                                        trackDetailList.add(trackDetail);
                                        ls_tracking_time = track.getTrackOccurDate().toString();
                                        ls_tracking_info = track.getTrackDescription();
                                        trackingInfoNew.setOrderId(order.getId());
                                        trackingInfoNew.setTrackingNo(order.getResponseTrackNumber());
                                        trackingInfoNew.setTotalWeight(order.getTotalWeight().toString());
                                        trackingInfoNew.setMessage(ls_tracking_info);
                                        trackingInfoNew.setSendTime(ls_tracking_time);
                                        orderLabelBiz.saveTrackInfo(trackingInfoNew);
                                        //如果是送达的最后状态，需要更新Order状态，下次不用再次发送Tracking信息
                                        String ls_tracking_status = autoCalculateStatus(ls_tracking_info);
                                        if (ls_tracking_info.equals("DELIVERED")) {orderLabelBiz.updateZhongTongTrackStatus(order.getId());}
                                    }
                                }
                                responseApiModel.setTrack(trackDetailList);
                            }
                        }
                    }
                } else {
                    //下游返回空处理
                    throw new BusinessException(messageSourceUtils.getMessage(
                            BaseOperatorConstant.ORDER_GET_TRACK_REQUEST_FAILED),
                            BaseOperatorConstant.ORDER_GET_TRACK_REQUEST_FAILED);
                }
            }
        } else {
            throw new BusinessException("未找到订单");
        }

        return responseApiModel;
    }

    /*
     * 创建飞鱼单条推送报文
     * 2021/01/01 20:00
     * */
    @Transactional
    public FishTrackResponseApiModel pushFishTrackSingleBatch(String tracking_no) {
        FishTrackResponseApiModel responseApiModel = new FishTrackResponseApiModel();
        FishTrackCreateRemoteResponse remoteResponse = new FishTrackCreateRemoteResponse();

        if (tracking_no == null || tracking_no == "" ){
            tracking_no = "%";
        }

        List<ShunfengOrderTrackingInfo> trackingList = trackingInfoMapper.selectList(new EntityWrapper<ShunfengOrderTrackingInfo>()
                .eq("is_send", 0)
                .eq("Delete_Yn", 0)
                .like("tracking_no", tracking_no)
                .isNotNull("order_id"));

        List<OrderGetTrackDetailResponseApiModel> trackDetailList = new ArrayList<>();
        if (ListUtils.isNotEmpty(trackingList)) {
            for (ShunfengOrderTrackingInfo trackDetail : trackingList) {
                remoteResponse = pushFishTrackSingle(trackDetail.getSendTime(), trackDetail.getMessage(),
                        trackDetail.getTrackingNo(), trackDetail.getTotalWeight(),trackDetail.getId() );

                OrderGetTrackDetailResponseApiModel trackDetailTemp = new OrderGetTrackDetailResponseApiModel();
                trackDetailTemp.setOccurTime(trackDetail.getInTime());
                trackDetailTemp.setDescription(trackDetail.getMessage());
                trackDetailList.add(trackDetailTemp);

            }
            responseApiModel.setTrack(trackDetailList);
        }
        responseApiModel.setCode(remoteResponse.getCode());
        responseApiModel.setStatus(remoteResponse.getStatus());
        responseApiModel.setMessage(remoteResponse.getMessage());
        responseApiModel.setTimestamp(remoteResponse.getTimestamp());
        responseApiModel.setStatusCode(remoteResponse.getStatusCode());
        responseApiModel.setStatusCodeValue(remoteResponse.getStatusCodeValue());
        return responseApiModel;
    }
    /*
     * 创建飞鱼单条推送报文
     * 2020/12/29
     * */

    public FishTrackCreateRemoteResponse pushFishTrackSingle(String tracking_time,String tracking_info,
                                                             String tracking_no,String tracking_weight,Long trackId) {
        String ls_city = autoCalculateCity(tracking_info);
        String ls_tracking_status = autoCalculateStatus(tracking_info);
        String ls_tracking_country = autoCalculateCountry(tracking_info);

        FishTrackCreateRemoteRequest remoteRequest = new FishTrackCreateRemoteRequest();
        remoteRequest.setTrackingType("CLEARANCE");// required
        FishTrackCreateTracksRemoteRequest tracks = new FishTrackCreateTracksRemoteRequest();// required
        tracks.setDestinationCountryCode("US");// required
        tracks.setOriginCountryCode("CN");// required
        tracks.setTrackingNumber(tracking_no);// required
        tracks.setTrackingStatus("OTHER");// required

        FishTrackCreateTracksPointRemoteRequest trackPoint = new FishTrackCreateTracksPointRemoteRequest();
        trackPoint.setCheckpointTime(tracking_time);// required
        trackPoint.setCity(ls_city);// required
        trackPoint.setCountryCode(ls_tracking_country);// required
        trackPoint.setFailedCode(ls_tracking_status);// required
        trackPoint.setLocation(ls_city);// required
        trackPoint.setMessage(ls_tracking_status);// required  tracking_info  不接受中文
        trackPoint.setPostalCode("");
        trackPoint.setTimezone ("UTC");// required
        trackPoint.setState("");
        trackPoint.setTrackingStatus(ls_tracking_status);// required
        trackPoint.setWeight(tracking_weight);// required
        trackPoint.setEventStatus("SUCCESS");// required
        tracks.setCheckpoint(trackPoint);
        remoteRequest.setTrackings(tracks);

        FishTrackCreateRemoteResponse remoteResponse = this.formRequestFish(FLY_FISH_TRACK_PUSH_URL, remoteRequest,
                ParameterizedTypeReference.forType(FishTrackCreateRemoteResponse.class));

        if (remoteResponse != null) {
            //如果下游处理失败，将失败原因往外抛
            if (remoteResponse.getData() == null) {
                //下游返回空处理
                throw new BusinessException(remoteResponse.getMessage(),
                        BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED);
            }
            else {
           // Tracking info send out successful, will update the record status.
                orderLabelBiz.updateTrackStatus(trackId);
            }
        } else {
            //下游返回空处理
            throw new BusinessException(messageSourceUtils.getMessage(
                    BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED),
                    BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED);
        }

        return remoteResponse;
    }

    /*
     * 计算快件所在的国家
     * */
    public String autoCalculateCountry(String tracking_info){
        String ls_country = "CN";
        boolean country = (tracking_info.contains("美国") || tracking_info.contains("US"));
        if(country){  ls_country =  "US";}
        return ls_country;
    }

    /*
    * 计算Tracking的城市
    * */
    public String autoCalculateCity(String tracking_info){
        String ls_city = "OTHER";
        boolean statusShanghai = tracking_info.contains("上海");
        boolean statusHangzhou = tracking_info.contains("杭州");
        boolean statusChangsha = tracking_info.contains("长沙");
        boolean NEWYORK = tracking_info.contains("纽约");
        boolean LOSANGELES = tracking_info.contains("洛杉矶");

        if(statusShanghai){  ls_city =  "SHANGHAI";}
        if(statusHangzhou){ls_city =  "HANGZHOU"; }
        if(statusChangsha){ ls_city =  "CHANGSHA"; }
        if(NEWYORK){ ls_city =  "NEWYORK"; }
        if(LOSANGELES){ ls_city =  "LOSANGELES"; }
      return ls_city;
    }
    /*
     * 计算Tracking的 status
     * */
    public String autoCalculateStatus(String tracking_info){
        String ls_status = null;
        boolean WAYBILL_GENERATED = tracking_info.contains("Shipment");
        boolean PICK_UP = tracking_info.contains("已收取快件");
        boolean ARRIVE_FIRST_MILE = tracking_info.contains("快件在【上海闵行虹润营业点】");
        boolean DEPART_FIRST_MILE = (tracking_info.contains("快件已发车")||tracking_info.contains("上海虹桥中转场")||
                tracking_info.contains("上海国际小包操作中心") || tracking_info.contains("杭州萧山国际操作中心") ||
                tracking_info.contains("快件已发车") || tracking_info.contains("杭州萧山国际操作中心") ||
                tracking_info.contains("杭州机场关务站点"));
        boolean DEPART_AIRPORT = tracking_info.contains("已起飞");
        boolean ARRIVE_DEST_AIRPORT = (tracking_info.contains("快件到达"))&&(tracking_info.contains("美国"));
        boolean ARRIVE_DEST_CUSTOMS = (tracking_info.contains("快件到达") && tracking_info.contains("美国") && tracking_info.contains("关务组"));
        boolean DEPART_TRANSITHUB = (tracking_info.contains("请耐心等候") || tracking_info.contains("转运中"));
        boolean TRANSFER_LAST_MILE = tracking_info.contains("正在派送途中");
        boolean DELIVERED = tracking_info.contains("快件已经派送并签收");

        if(WAYBILL_GENERATED){ls_status =  "WAYBILL_GENERATED"; }
        if(PICK_UP){ls_status =  "PICK_UP"; }
        if(ARRIVE_FIRST_MILE){ls_status =  "ARRIVE_FIRST_MILE"; }
        if(DEPART_FIRST_MILE){ls_status =  "DEPART_FIRST_MILE"; }
        if(DEPART_AIRPORT){ls_status =  "DEPART_AIRPORT"; }
        if(ARRIVE_DEST_AIRPORT){ls_status =  "ARRIVE_DEST_AIRPORT"; }
        if(ARRIVE_DEST_CUSTOMS){ls_status =  "ARRIVE_DEST_CUSTOMS"; }
        if(DEPART_TRANSITHUB){ls_status =  "DEPART_TRANSITHUB"; }
        if(TRANSFER_LAST_MILE){ls_status =  "WAYBILL_GENERATED"; }
        if(DELIVERED){ls_status =  "DELIVERED"; }
        return ls_status;
    }
    /**
     * 包装下游请求公共参数（CusCode、ApiKey、CusApiName）
     *
     * @param requestApiModel
     * @param channelId
     * @param <T>
     * @return
     */
    private <T extends RequestBaseModel> T setPackageChannelInfo(T requestApiModel, String channelId) {
        if (oopstonConfig.getBigPackChannelId().equalsIgnoreCase(channelId)) {
            //如果是大包渠道
            requestApiModel.setCusCode(oopstonConfig.getBigPackCusCode());
            requestApiModel.setApiKey(oopstonConfig.getBigPackApiKey());
            requestApiModel.setCusApiName("跃翰");
        } else if (oopstonConfig.getSmallPackChannelId().equalsIgnoreCase(channelId)) {
            //如果是小包渠道
            requestApiModel.setCusCode(oopstonConfig.getSmallPackCusCode());
            requestApiModel.setApiKey(oopstonConfig.getSmallPackApiKey());
            requestApiModel.setCusApiName("跃翰");
        }
        requestApiModel.setCusApiName(oopstonConfig.getApiName());
        return requestApiModel;
    }

    /**
     * RestTemplate请求方法
     *
     * @param restUrl
     * @param requestModel
     * @param resultClass
     * @param <T>
     * @return
     */
    private <T> T request(String restUrl, Object requestModel, ParameterizedTypeReference<T> resultClass) {
        if (StringUtils.isBlank(restUrl)) {
            return null;
        }
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        HttpEntity<Object> formEntity = new HttpEntity<>(requestModel, headers);
        ResponseEntity<T> resultContent = null;
        String requestHeader = "\n request header : " + getObjectContent(headers);
        String requestContent = "\n , request content : " + getObjectContent(requestModel);
        long startTime = System.currentTimeMillis();
        try {
            resultContent = restTemplate.exchange(restUrl, HttpMethod.POST, formEntity, resultClass);
        } catch (Exception ex) {
            logger.error("restClient request url : " + restUrl + requestHeader + requestContent + "\n , error message : " + ex.getMessage(), ex);
            resultContent = null;
        } finally {
            long endTime = System.currentTimeMillis();
            String responseContent = "\n , response result : " + getObjectContent(resultContent);
            logger.info("restClient request url : " + restUrl + " , use time : " + (endTime - startTime) + requestHeader + requestContent + responseContent);
        }
        return resultContent.getBody();
    }

    /**
     * RestTemplate请求方法
     *
     * @param restUrl
     * @param requestModel
     * @param resultClass
     * @param <T>
     * @return
     */
    private <T> T formRequest(String restUrl, String methodName, Object requestModel, ParameterizedTypeReference<T> resultClass) {
        if (StringUtils.isBlank(restUrl)) {
            return null;
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap map = new LinkedMultiValueMap();
        map.add("appToken", oopstonConfig.getZhongTongAppToken());
        map.add("appKey", oopstonConfig.getZhongTongAppKey());
        map.add("serviceMethod", methodName);
        map.add("paramsJson", JSONObject.toJSONString(requestModel));
        HttpEntity formEntity = new HttpEntity(map, headers);
        ResponseEntity<T> resultContent = null;
        String requestHeader = "\n request header : " + getObjectContent(headers);
        String requestContent = "\n , request content : " + JSONObject.toJSONString(requestModel);
        long startTime = System.currentTimeMillis();
        try {
            resultContent = restTemplate.exchange(restUrl, HttpMethod.POST, formEntity, resultClass);
        } catch (Exception ex) {
            logger.error("restClient request url : " + restUrl + requestHeader + requestContent + "\n , error message : " + ex.getMessage(), ex);
            resultContent = null;
        } finally {
            long endTime = System.currentTimeMillis();
            String responseContent = "\n , response result : " + getObjectContent(resultContent);
            logger.info("restClient request url : " + restUrl + " , use time : " + (endTime - startTime) + requestHeader + requestContent + responseContent);
        }
        return resultContent.getBody();
    }

    /**
     * RestTemplate请求方法
     *
     * @param restUrl
     * @param requestModel
     * @param resultClass
     * @param <T>
     * @return
     */
    private <T> T formRequestFish(String restUrl, Object requestModel, ParameterizedTypeReference<T> resultClass) {
        String body = JSONObject.toJSONString(requestModel);
       // String appSecret ="58644a4453fe1ee5f6b394287901ac37";//test
        String appSecret ="33cea427ad15e1e1610bae3e20739fba";//product
        String str = body + appSecret;	// 生成一个 MD5 加密计算摘要
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            System.out.println("NoSuchAlgorithmException caught!");
            System.exit(-1);
        }
        // 计算 md5 函数
        md.update(str.getBytes());
        byte[] hash = md.digest();
        byte[] encoded = Base64.getEncoder().encode(hash);
        String digest = new String(encoded);
        System.out.println(digest);
        System.out.println(body);
        if (StringUtils.isBlank(restUrl)) {
            return null;
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        //headers.add("cpCode", "test");//test
        headers.add("cpCode", "62e7a166");//product
        headers.add("digest", digest);
        HttpEntity<Object> formEntity = new HttpEntity(JSONObject.toJSONString(requestModel), headers);
        ResponseEntity<T> resultContent = null;
        String requestHeader = "\n request header : " + getObjectContent(headers);
        String requestContent = "\n , request content : " + JSONObject.toJSONString(requestModel);
        long startTime = System.currentTimeMillis();
        try {
            resultContent = restTemplate.exchange(restUrl, HttpMethod.POST, formEntity, resultClass);
        } catch (Exception ex) {
            logger.error("restClient request url : " + restUrl + requestHeader + requestContent + "\n , error message : " + ex.getMessage(), ex);
            resultContent = null;
        } finally {
            long endTime = System.currentTimeMillis();
            String responseContent = "\n , response result : " + getObjectContent(resultContent);
            logger.info("restClient request url : " + restUrl + " , use time : " + (endTime - startTime) + requestHeader + requestContent + responseContent);
        }
        return resultContent.getBody();
    }

    /**
     * JSON序列化出入参
     *
     * @param object
     * @return
     */
    private String getObjectContent(Object object) {
        if (object == null) {
            return "";
        }

        try {
            return objectMapper.writeValueAsString(object);
        } catch (IOException e) {
            logger.error("getObjectContent writeValueAsString error." + e.getMessage(), e);
        }
        return "";
    }

    private OrderCreateRemoteRequest buildCreateOrderRemoteRequest(OrderCreateRequestApiModel requestApiModel) {
        OrderCreateRemoteRequest remoteRequest = new OrderCreateRemoteRequest();
        remoteRequest.setStyle(requestApiModel.getOrderType());
        remoteRequest.setSender(requestApiModel.getShipperContactsName());
        remoteRequest.setSignFlag(requestApiModel.getSignType());
        remoteRequest.setSendAddress(requestApiModel.getShipperAddress());
        remoteRequest.setSendPhone(requestApiModel.getShipperContactsPhone());
        remoteRequest.setSendEmail(requestApiModel.getShipperContactsEmail());
        remoteRequest.setSendCompany(requestApiModel.getShipperCompanyName());
        remoteRequest.setConsigneeName(requestApiModel.getConsigneeCompanyName());
        remoteRequest.setCountry(requestApiModel.getConsigneeCountry());
        if (requestApiModel.getQuantity() > 1) {
            remoteRequest.setBase_ChannelInfoID(oopstonConfig.getBigPackChannelId());
        } else {
            remoteRequest.setBase_ChannelInfoID(oopstonConfig.getSmallPackChannelId());
        }
        remoteRequest.setState(requestApiModel.getConsigneeState());
        remoteRequest.setCity(requestApiModel.getConsigneeCity());
        remoteRequest.setAddress1(requestApiModel.getConsigneeAddress1());
        remoteRequest.setAddress2(requestApiModel.getConsigneeAddress2());
        remoteRequest.setCsRefNo(requestApiModel.getReferenceNo());
        remoteRequest.setOrderStatus(CommonConstants.BYTE_THREE);
        remoteRequest.setZipcode(requestApiModel.getConsigneeZipcode());
        remoteRequest.setContact(requestApiModel.getConsigneeContactsPhone());
        remoteRequest.setStorteID(requestApiModel.getWarehouseId());
        remoteRequest.setCompanyName(requestApiModel.getConsigneeCompanyName());
        remoteRequest.setCusRemark(requestApiModel.getOrderRemark());
        remoteRequest.setRecipientEmail(requestApiModel.getConsigneeContactsEmail());
        remoteRequest.setBillQty(requestApiModel.getQuantity());

        List<OrderBagRemoteRequest> orderBags = new ArrayList<>();
        for (OrderPackageCreateRequestApiModel orderPackage : requestApiModel.getOrderPackages()) {
            OrderBagRemoteRequest orderBag = new OrderBagRemoteRequest();
            orderBag.setWeight(orderPackage.getWeight());
            orderBag.setLength(orderPackage.getLength());
            orderBag.setWidth(orderPackage.getWidth());
            orderBag.setHeight(orderPackage.getHeight());
            orderBags.add(orderBag);
        }
        remoteRequest.setOrderBags(orderBags);

        List<OrderProductRemoteRequest> products = new ArrayList<>();
        for (OrderSkuCreateRequestApiModel orderSku : requestApiModel.getOrderProducts()) {
            OrderProductRemoteRequest product = new OrderProductRemoteRequest();
            product.setSku(orderSku.getSku());
            product.setEnName(sensitiveWordFilter.replaceSensitiveWord(orderSku.getSkuEnglishName(),1,""));
            product.setCnName(sensitiveWordFilter.replaceSensitiveWord(orderSku.getSkuChineseName(),1,""));
            product.setQty(orderSku.getQuantity());
            product.setWeight(orderSku.getWeight());
            product.setPrice(orderSku.getPrice());
            product.setHsCode(orderSku.getHsCode());
            product.setProducingArea(orderSku.getProducingArea());
            products.add(product);
        }
        remoteRequest.setProducts(products);
        return remoteRequest;
    }

    /**
     * 创建中通订单
     *
     * @param requestApiModel
     */
    @Transactional
    public OrderCreateResponseApiModel createOrder2(ZhongTongOrderCreateRequestApiModel requestApiModel) {
        requestApiModel.setCargoType("W");
        OrderCreateResponseApiModel responseApiModel = new OrderCreateResponseApiModel();
        List<OopstonOrder> oopstonOrderList = oopstonOrderMapper.selectList(new EntityWrapper<OopstonOrder>().eq("Delete_Yn", YesNoEnum.NO.getKey())
                .eq("Cancel_Status", YesNoEnum.NO.getKey())
                .eq("Order_Ref_No",requestApiModel.getReferenceNo())
                .in("Channel_Type", Arrays.asList(ChannelTypeEnum.USUSPS_F.getKey(), ChannelTypeEnum.USUSPS_P.getKey(), ChannelTypeEnum.USDHL_E.getKey(), ChannelTypeEnum.Fedex_smart_post.getKey()))
                .isNotNull("Response_Order_ID"));

        if (ListUtils.isNotEmpty(oopstonOrderList)) {
            responseApiModel.setOrderId(String.valueOf(oopstonOrderList.get(0).getId()));
            responseApiModel.setReferenceNo(oopstonOrderList.get(0).getOrderRefNo());
            responseApiModel.setTrackNumber(oopstonOrderList.get(0).getResponseTrackNumber());
            return responseApiModel;
        }
        OopstonOrder order = orderLabelBiz.createZhongTongOrderInfo(requestApiModel);

        //封装接口参数
        ZhongTongOrderCreateRemoteRequest remoteRequest = buildZhongTongCreateOrderRemoteRequest(requestApiModel);

        ZhongTongOrderCreateRemoteResponse remoteResponse = this.formRequest(ZHONG_TONG_REQUEST_URL, ZHONG_TONG_ORDER_CREATE_METHOD, remoteRequest,
                ParameterizedTypeReference.forType(ZhongTongOrderCreateRemoteResponse.class));

        if (remoteResponse != null) {
            //如果下游处理失败，将失败原因往外抛
            if (CommonConstants.STRING_ZERO.equalsIgnoreCase(remoteResponse.getSuccess()) || remoteResponse.getData() == null) {
                //下游返回空处理
                throw new BusinessException(remoteResponse.getCnmessage(),
                        BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED);
            } else {
                orderLabelBiz.updateZhongTongResponse(order.getId(), remoteResponse);
            }
        } else {
            //下游返回空处理
            throw new BusinessException(messageSourceUtils.getMessage(
                    BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED),
                    BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED);
        }
        responseApiModel.setOrderId(String.valueOf(order.getId()));
        responseApiModel.setReferenceNo(requestApiModel.getReferenceNo());
        responseApiModel.setTrackNumber(remoteResponse.getData().getShipping_method_no());
        return responseApiModel;
    }

    /*
    * 创建飞鱼推送报文  测试成功
    * 2020/12/27
    * */
    @Transactional
    public FishTrackResponseApiModel pushFishTrack(Long orderId) {//测试成功
        FishTrackResponseApiModel responseApiModel = new FishTrackResponseApiModel();
        //封装接口参数
       // FishTrackCreateRemoteRequest remoteRequest = buildZhongTongCreateOrderRemoteRequest(requestApiModel);
        FishTrackCreateRemoteRequest remoteRequest = new FishTrackCreateRemoteRequest();

        remoteRequest.setTrackingType("CLEARANCE");
        FishTrackCreateTracksRemoteRequest tracks = new FishTrackCreateTracksRemoteRequest();
        tracks.setDestinationCountryCode("US");
        tracks.setOriginCountryCode("CN");
        tracks.setTrackingNumber("YT1934500110014479");
        tracks.setTrackingStatus("OTHER");

        FishTrackCreateTracksPointRemoteRequest trackPoint = new FishTrackCreateTracksPointRemoteRequest();
        trackPoint.setCheckpointTime("2019-12-13T10:51:56+00:00");
        trackPoint.setCity("SHENZHEN");
        trackPoint.setCountryCode("CN");
        trackPoint.setFailedCode("");
        trackPoint.setLocation("SHENZHEN");
        trackPoint.setMessage("PICK_UP");
        trackPoint.setPostalCode("322000");
        trackPoint.setTimezone ("UTC");
        trackPoint.setState("GUANGDONG");
        trackPoint.setTrackingStatus("PICK_UP");
        trackPoint.setWeight("0.126");
        trackPoint.setEventStatus("SUCCESS");
        tracks.setCheckpoint(trackPoint);
        remoteRequest.setTrackings(tracks);

        FishTrackCreateRemoteResponse remoteResponse = this.formRequestFish(FLY_FISH_TRACK_PUSH_URL, remoteRequest,
                ParameterizedTypeReference.forType(FishTrackCreateRemoteResponse.class));

        if (remoteResponse != null) {
            //如果下游处理失败，将失败原因往外抛
            if (remoteResponse.getData() == null) {
                //下游返回空处理
                throw new BusinessException(remoteResponse.getMessage(),
                        BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED);
            } else {
                //orderLabelBiz.updateZhongTongResponse(order.getId(), remoteResponse);

            }
        } else {
            //下游返回空处理
            throw new BusinessException(messageSourceUtils.getMessage(
                    BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED),
                    BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED);
        }
        responseApiModel.setData(remoteResponse.getData());
        responseApiModel.setCode(remoteResponse.getCode());
        responseApiModel.setStatus(remoteResponse.getStatus());
        responseApiModel.setMessage(remoteResponse.getMessage());
        responseApiModel.setTimestamp(remoteResponse.getTimestamp());
        responseApiModel.setStatusCode(remoteResponse.getStatusCode());
        responseApiModel.setStatusCodeValue(remoteResponse.getStatusCodeValue());
        return responseApiModel;
    }

    /*
     * 创建飞鱼推送报文 测试成功
     * 2020/12/27
     * */
    @Transactional
    public FishTrackResponseApiModel pushFishTrack1( Long id) {
        FishTrackResponseApiModel responseApiModel = new FishTrackResponseApiModel();


        String ls_abc = "快件到达【纽约】，准备发往【美国纽约口岸】";
        String ls_time = "2020-12-21 16:51:00";
        String ls_tracking_time,ls_tracking_info,ls_tracking_no,ls_tracking_weight;
        Long ll_id = Long.valueOf(11222);

        ls_tracking_time = "2020-12-21 16:51:00";
        ls_tracking_info = "快件到达【纽约】，准备发往【美国纽约口岸】";
        ls_tracking_no = "SF6043063143432";
        ls_tracking_weight = "0.1000";

        String tracking_time = ls_time,tracking_info = ls_tracking_info, tracking_no = ls_tracking_no,tracking_weight =ls_tracking_weight;
        Long trackId = null;

        String ls_city = autoCalculateCity(tracking_info);
        String ls_tracking_status = autoCalculateStatus(tracking_info);
        String ls_tracking_country = autoCalculateCountry(tracking_info);
        FishTrackCreateRemoteRequest remoteRequest = new FishTrackCreateRemoteRequest();


        remoteRequest.setTrackingType("CLEARANCE");// required
        FishTrackCreateTracksRemoteRequest tracks = new FishTrackCreateTracksRemoteRequest();// required
        tracks.setDestinationCountryCode("US");// required
        tracks.setOriginCountryCode("CN");// required
        tracks.setTrackingNumber(tracking_no);// required
        tracks.setTrackingStatus("OTHER");// required

        FishTrackCreateTracksPointRemoteRequest trackPoint = new FishTrackCreateTracksPointRemoteRequest();
        trackPoint.setCheckpointTime(tracking_time);// required
        trackPoint.setCity(ls_city);// required
        trackPoint.setCountryCode(ls_tracking_country);// required
        trackPoint.setFailedCode(ls_tracking_status);// required
        trackPoint.setLocation(ls_city);// required
        trackPoint.setMessage(ls_tracking_status);// required
        trackPoint.setPostalCode("");
        trackPoint.setTimezone ("UTC");// required
        trackPoint.setState("");
        trackPoint.setTrackingStatus(ls_tracking_status);// required
        trackPoint.setWeight(tracking_weight);// required
        trackPoint.setEventStatus("SUCCESS");// required
        tracks.setCheckpoint(trackPoint);
        remoteRequest.setTrackings(tracks);

/*
        remoteRequest.setTrackingType("CLEARANCE");// required
        FishTrackCreateTracksRemoteRequest tracks = new FishTrackCreateTracksRemoteRequest();// required
        tracks.setDestinationCountryCode("US");// required
        tracks.setOriginCountryCode("CN");// required
        tracks.setTrackingNumber("YT1934500110014479");// required
        tracks.setTrackingStatus("OTHER");// required

        FishTrackCreateTracksPointRemoteRequest trackPoint = new FishTrackCreateTracksPointRemoteRequest();
        trackPoint.setCheckpointTime("2019-12-13T10:51:56+00:00");// required
        trackPoint.setCity("SHENZHEN");// required
        trackPoint.setCountryCode("CN");// required
        trackPoint.setFailedCode("");// required
        trackPoint.setLocation("SHENZHEN");// required
        trackPoint.setMessage("快件到达【纽约】，准备发往【美国纽约口岸】");// required
        trackPoint.setPostalCode("");
        trackPoint.setTimezone ("UTC");// required
        trackPoint.setState("");
        trackPoint.setTrackingStatus(ls_tracking_status);// required
        trackPoint.setWeight(tracking_weight);// required
        trackPoint.setEventStatus("SUCCESS");// required
        tracks.setCheckpoint(trackPoint);
        remoteRequest.setTrackings(tracks);


        remoteRequest.setTrackingType("CLEARANCE");
        FishTrackCreateTracksRemoteRequest tracks = new FishTrackCreateTracksRemoteRequest();
        tracks.setDestinationCountryCode("US");
        tracks.setOriginCountryCode("CN");
        tracks.setTrackingNumber("YT1934500110014479");
        tracks.setTrackingStatus("OTHER");

        FishTrackCreateTracksPointRemoteRequest trackPoint = new FishTrackCreateTracksPointRemoteRequest();
        trackPoint.setCheckpointTime("2019-12-13T10:51:56+00:00");
        trackPoint.setCity("SHENZHEN");
        trackPoint.setCountryCode("CN");
        trackPoint.setFailedCode("");
        trackPoint.setLocation("SHENZHEN");
        trackPoint.setMessage("PICK_UP");
        trackPoint.setPostalCode("322000");
        trackPoint.setTimezone ("UTC");
        trackPoint.setState("GUANGDONG");
        trackPoint.setTrackingStatus("PICK_UP");
        trackPoint.setWeight("0.126");
        trackPoint.setEventStatus("SUCCESS");
        tracks.setCheckpoint(trackPoint);
        remoteRequest.setTrackings(tracks);
*/
        FishTrackCreateRemoteResponse remoteResponse = this.formRequestFish(FLY_FISH_TRACK_PUSH_URL, remoteRequest,
                ParameterizedTypeReference.forType(FishTrackCreateRemoteResponse.class));

       // FishTrackCreateRemoteResponse remoteResponse = pushFishTrackSingle(ls_tracking_time,ls_tracking_info,ls_tracking_no,ls_tracking_weight,ll_id);
       // FishTrackResponseApiModel responseApiModel = new FishTrackResponseApiModel();

        if (remoteResponse != null) {
            //如果下游处理失败，将失败原因往外抛
            if (remoteResponse.getData() == null) {
                //下游返回空处理
                throw new BusinessException(remoteResponse.getMessage(),
                        BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED);
            } else {
                //orderLabelBiz.updateZhongTongResponse(order.getId(), remoteResponse);

            }
        } else {
            //下游返回空处理
            throw new BusinessException(messageSourceUtils.getMessage(
                    BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED),
                    BaseOperatorConstant.ORDER_CREATE_REQUEST_FAILED);
        }
        responseApiModel.setData(remoteResponse.getData());
        responseApiModel.setCode(remoteResponse.getCode());
        responseApiModel.setStatus(remoteResponse.getStatus());
        responseApiModel.setMessage(remoteResponse.getMessage());
        responseApiModel.setTimestamp(remoteResponse.getTimestamp());
        responseApiModel.setStatusCode(remoteResponse.getStatusCode());
        responseApiModel.setStatusCodeValue(remoteResponse.getStatusCodeValue());
        return responseApiModel;
    }

/*
    private FishTrackCreateRemoteRequest buildFishTrackCreateRemoteRequest(FishTrackCreateRequestApiModel requestApiModel) {
        FishTrackCreateRemoteRequest remoteRequest = new FishTrackCreateRemoteRequest();
        remoteRequest.setReferenceNo(requestApiModel.getReferenceNo());
        String shippingMethod = ShippingMethodEnum.getValueByKey(requestApiModel.getShippingMethod());
        remoteRequest.setShippingMethod(shippingMethod);
        remoteRequest.setOrderWeight(String.valueOf(requestApiModel.getWeight()));
        remoteRequest.setOrderPieces(String.valueOf(requestApiModel.getQuantity()));
        remoteRequest.setCargoType(requestApiModel.getCargoType());
        remoteRequest.setMailCargoType(requestApiModel.getMailCargoType());
        remoteRequest.setReturnSign(requestApiModel.getReturnSign());
        remoteRequest.setBuyerId(requestApiModel.getBuyerId());
        remoteRequest.setOrderInfo(requestApiModel.getOrderRemark());

        ZhongTongShipperRemoteRequest shipper = new ZhongTongShipperRemoteRequest();
        shipper.setShipperName(requestApiModel.getShipperContactsName());
        shipper.setShipperCompany(requestApiModel.getShipperCompanyName());
        shipper.setShipperCountryCode(requestApiModel.getShipperCountry());
        shipper.setShipperProvince(requestApiModel.getShipperState());
        shipper.setShipperCity(requestApiModel.getShipperCity());
        shipper.setShipperDistrict(requestApiModel.getShipperDistrict());
        shipper.setShipperStreet(requestApiModel.getShipperAddress());
        shipper.setShipperPostCode(requestApiModel.getShipperZipcode());
        shipper.setShipperAreaCode(requestApiModel.getShipperArea());
        shipper.setShipperTelephone(requestApiModel.getShipperContactsPhone());
        shipper.setShipperMobile(requestApiModel.getShipperMobile());
        shipper.setShipperEmail(requestApiModel.getShipperContactsEmail());
        shipper.setShipperFax(requestApiModel.getShipperFax());
        remoteRequest.setShipper(shipper);




        List<ZhongTongInvoiceRemoteRequest> invoices = new ArrayList<>();
        for (OrderSkuCreateRequestApiModel orderSku : requestApiModel.getOrderProducts()) {
            ZhongTongInvoiceRemoteRequest invoice = new ZhongTongInvoiceRemoteRequest();
            invoice.setSku(orderSku.getSku());
            invoice.setInvoiceEnName(sensitiveWordFilter.replaceSensitiveWord(orderSku.getSkuEnglishName(),1,""));
            invoice.setInvoiceCnName(sensitiveWordFilter.replaceSensitiveWord(orderSku.getSkuChineseName(),1,""));
            invoice.setInvoiceQuantity(String.valueOf(orderSku.getQuantity()));
            invoice.setInvoiceUnitCharge(String.valueOf(orderSku.getPrice()));
            invoice.setHsCode(orderSku.getHsCode());
            invoice.setInvoiceNote(orderSku.getInvoiceNote());
            invoice.setInvoiceUrl(orderSku.getInvoiceUrl());
            invoice.setInvoiceInfo(orderSku.getInvoiceInfo());
            invoice.setInvoiceMaterial(orderSku.getInvoiceMaterial());
            invoice.setInvoiceSpec(orderSku.getSpec());
            invoice.setInvoiceUse(orderSku.getUse());
            invoice.setInvoiceBrand(orderSku.getBrand());
            invoice.setPosttaxNum(orderSku.getPosttaxNum());

            invoices.add(invoice);
        }
        remoteRequest.setInvoice(invoices);

        if (ListUtils.isNotEmpty(requestApiModel.getExtraServices())) {
            List<ZhongTongExtraServiceRemoteRequest> extraServices = new ArrayList<>();
            for (ZhongTongOrderExtraServiceRequestApiModel orderExtraService : requestApiModel.getExtraServices()) {
                ZhongTongExtraServiceRemoteRequest extraService = new ZhongTongExtraServiceRemoteRequest();
                extraService.setExtraServiceCode(orderExtraService.getExtraServiceCode());
                extraService.setExtraServiceValue(orderExtraService.getExtraServiceValue());
                extraService.setExtraServiceNote(orderExtraService.getExtraServiceNote());

                extraServices.add(extraService);
            }

            remoteRequest.setExtraService(extraServices);
        }
        return remoteRequest;
    }
*/
    private ZhongTongOrderCreateRemoteRequest buildZhongTongCreateOrderRemoteRequest(ZhongTongOrderCreateRequestApiModel requestApiModel) {
        ZhongTongOrderCreateRemoteRequest remoteRequest = new ZhongTongOrderCreateRemoteRequest();
        remoteRequest.setReferenceNo(requestApiModel.getReferenceNo());
        String shippingMethod = ShippingMethodEnum.getValueByKey(requestApiModel.getShippingMethod());
        remoteRequest.setShippingMethod(shippingMethod);
        remoteRequest.setOrderWeight(String.valueOf(requestApiModel.getWeight()));
        remoteRequest.setOrderPieces(String.valueOf(requestApiModel.getQuantity()));
        remoteRequest.setCargoType(requestApiModel.getCargoType());
        remoteRequest.setMailCargoType(requestApiModel.getMailCargoType());
        remoteRequest.setReturnSign(requestApiModel.getReturnSign());
        remoteRequest.setBuyerId(requestApiModel.getBuyerId());
        remoteRequest.setOrderInfo(requestApiModel.getOrderRemark());

        ZhongTongShipperRemoteRequest shipper = new ZhongTongShipperRemoteRequest();
        shipper.setShipperName(requestApiModel.getShipperContactsName());
        shipper.setShipperCompany(requestApiModel.getShipperCompanyName());
        shipper.setShipperCountryCode(requestApiModel.getShipperCountry());
        shipper.setShipperProvince(requestApiModel.getShipperState());
        shipper.setShipperCity(requestApiModel.getShipperCity());
        shipper.setShipperDistrict(requestApiModel.getShipperDistrict());
        shipper.setShipperStreet(requestApiModel.getShipperAddress());
        shipper.setShipperPostCode(requestApiModel.getShipperZipcode());
        shipper.setShipperAreaCode(requestApiModel.getShipperArea());
        shipper.setShipperTelephone(requestApiModel.getShipperContactsPhone());
        shipper.setShipperMobile(requestApiModel.getShipperMobile());
        shipper.setShipperEmail(requestApiModel.getShipperContactsEmail());
        shipper.setShipperFax(requestApiModel.getShipperFax());
        remoteRequest.setShipper(shipper);

        ZhongTongConsigneeRemoteRequest consignee = new ZhongTongConsigneeRemoteRequest();
        consignee.setConsigneeName(requestApiModel.getConsigneeContactsName());
        consignee.setConsigneeCompany(requestApiModel.getConsigneeCompanyName());
        consignee.setConsigneeCountryCode(requestApiModel.getConsigneeCountry());
        consignee.setConsigneeProvince(requestApiModel.getConsigneeState());
        consignee.setConsigneeCity(requestApiModel.getConsigneeCity());
        consignee.setConsigneeDistrict(requestApiModel.getConsigneeDistrict());
        consignee.setConsigneeStreet(requestApiModel.getConsigneeAddress1());
        consignee.setConsigneePostCode(requestApiModel.getConsigneeZipcode());
        consignee.setConsigneeDoorplate(requestApiModel.getConsigneeDoorplate());
        consignee.setConsigneeAreaCode(requestApiModel.getConsigneeArea());
        consignee.setConsigneeTelephone(requestApiModel.getConsigneeContactsPhone());
        consignee.setConsigneeMobile(requestApiModel.getConsigneeMobile());
        consignee.setConsigneeEmail(requestApiModel.getConsigneeContactsEmail());
        consignee.setConsigneeFax(requestApiModel.getConsigneeFax());
        consignee.setConsigneeCertificateType(requestApiModel.getConsigneeCertificateType());
        consignee.setConsigneeCertificateCode(requestApiModel.getConsigneeCertificateCode());
        consignee.setConsigneeCredentialsPeriod(requestApiModel.getConsigneeCredentialsPeriod());
        consignee.setConsigneeTariff(requestApiModel.getConsigneeTariff());
        remoteRequest.setConsignee(consignee);


        List<ZhongTongInvoiceRemoteRequest> invoices = new ArrayList<>();
        for (OrderSkuCreateRequestApiModel orderSku : requestApiModel.getOrderProducts()) {
            ZhongTongInvoiceRemoteRequest invoice = new ZhongTongInvoiceRemoteRequest();
            invoice.setSku(orderSku.getSku());
            invoice.setInvoiceEnName(sensitiveWordFilter.replaceSensitiveWord(orderSku.getSkuEnglishName(),1,""));
            invoice.setInvoiceCnName(sensitiveWordFilter.replaceSensitiveWord(orderSku.getSkuChineseName(),1,""));
            invoice.setInvoiceQuantity(String.valueOf(orderSku.getQuantity()));
            invoice.setInvoiceUnitCharge(String.valueOf(orderSku.getPrice()));
            invoice.setHsCode(orderSku.getHsCode());
            invoice.setInvoiceNote(orderSku.getInvoiceNote());
            invoice.setInvoiceUrl(orderSku.getInvoiceUrl());
            invoice.setInvoiceInfo(orderSku.getInvoiceInfo());
            invoice.setInvoiceMaterial(orderSku.getInvoiceMaterial());
            invoice.setInvoiceSpec(orderSku.getSpec());
            invoice.setInvoiceUse(orderSku.getUse());
            invoice.setInvoiceBrand(orderSku.getBrand());
            invoice.setPosttaxNum(orderSku.getPosttaxNum());

            invoices.add(invoice);
        }
        remoteRequest.setInvoice(invoices);

        if (ListUtils.isNotEmpty(requestApiModel.getExtraServices())) {
            List<ZhongTongExtraServiceRemoteRequest> extraServices = new ArrayList<>();
            for (ZhongTongOrderExtraServiceRequestApiModel orderExtraService : requestApiModel.getExtraServices()) {
                ZhongTongExtraServiceRemoteRequest extraService = new ZhongTongExtraServiceRemoteRequest();
                extraService.setExtraServiceCode(orderExtraService.getExtraServiceCode());
                extraService.setExtraServiceValue(orderExtraService.getExtraServiceValue());
                extraService.setExtraServiceNote(orderExtraService.getExtraServiceNote());

                extraServices.add(extraService);
            }

            remoteRequest.setExtraService(extraServices);
        }
        return remoteRequest;
    }

    @Transactional
    public OrderGetTagResponseApiModel getTag(OrderGetTagRequestApiModel requestApiModel) {
        OrderGetTagResponseApiModel responseApiModel = new OrderGetTagResponseApiModel();
        responseApiModel.setOrderId(requestApiModel.getOrderId());
        OopstonOrder order = oopstonOrderMapper.selectById(requestApiModel.getOrderId());
        if (order != null) {
            if (Arrays.asList(ChannelTypeEnum.FBA_USOUG.getKey(), ChannelTypeEnum.FBA_USOFG.getKey(), ChannelTypeEnum.FBA_USAFG.getKey(), ChannelTypeEnum.FBA_USAUG.getKey())
                    .contains(order.getChannelType())) {
                responseApiModel.setPrintUrl("http://yhos.john-logistics.com" + WebUtil.getFile(order.getResponsePrintUrl()));
            } else if (Arrays.asList(ChannelTypeEnum.USUSPS_F.getKey(), ChannelTypeEnum.USUSPS_P.getKey(), ChannelTypeEnum.USDHL_E.getKey(), ChannelTypeEnum.Fedex_smart_post.getKey())
                    .contains(order.getChannelType())) {
                if(StringUtils.isBlank(order.getResponsePrintUrl())){
                    ZhongTongGetNewLabelRemoteRequest remoteRequest = new ZhongTongGetNewLabelRemoteRequest();

                    ZhongTongConfigInfoRemoteRequest configInfo = new ZhongTongConfigInfoRemoteRequest();
                    configInfo.setLabelFileType(CommonConstants.STRING_ONE);
                    configInfo.setLabelPaperType(CommonConstants.STRING_ONE);
                    configInfo.setLabelContentType(CommonConstants.STRING_ONE);

                    ZhongTongAdditionalInfoRemoteRequest additionalInfo = new ZhongTongAdditionalInfoRemoteRequest();
                    additionalInfo.setLabelPrintInvoiceInfo("Y");
                    additionalInfo.setLabelPrintBuyerId("N");
                    additionalInfo.setLabelPrintDateTime("Y");
                    additionalInfo.setCustomsDeclarationPrintActualWeight("N");
                    configInfo.setAdditionalInfo(additionalInfo);

                    List<ZhongTongListOrderRemoteRequest> listOrders = new ArrayList<>();
                    ZhongTongListOrderRemoteRequest listOrder = new ZhongTongListOrderRemoteRequest();
                    listOrder.setReferenceNo(order.getOrderRefNo());
                    listOrders.add(listOrder);

                    remoteRequest.setConfigInfo(configInfo);
                    remoteRequest.setListOrder(listOrders);

                    ZhongTongGetNewLabelRemoteResponse remoteResponse = this.formRequest(ZHONG_TONG_REQUEST_URL, ZHONG_TONG_TAG_GET_METHOD, remoteRequest,
                            ParameterizedTypeReference.forType(ZhongTongGetNewLabelRemoteResponse.class));

                    if (remoteResponse != null) {
                        //如果下游处理失败，将失败原因往外抛
                        if (CommonConstants.STRING_ZERO.equalsIgnoreCase(remoteResponse.getSuccess()) || remoteResponse.getData() == null) {
                            //下游返回空处理
                            throw new BusinessException(remoteResponse.getCnmessage(),
                                    BaseOperatorConstant.ORDER_GET_TAG_REQUEST_FAILED);
                        } else {
                            orderLabelBiz.updateZhongTongGetTagResponse(order.getId(), remoteResponse);
                            if(ListUtils.isNotEmpty(remoteResponse.getData())){
                                responseApiModel.setPrintUrl("http://yhos.john-logistics.com" + WebUtil.getFile(remoteResponse.getData().get(0).getLableFile()));
                            }
                        }
                    } else {
                        //下游返回空处理
                        throw new BusinessException(messageSourceUtils.getMessage(
                                BaseOperatorConstant.ORDER_GET_TAG_REQUEST_FAILED),
                                BaseOperatorConstant.ORDER_GET_TAG_REQUEST_FAILED);
                    }
                }else{
                    responseApiModel.setPrintUrl("http://yhos.john-logistics.com" + WebUtil.getFile(order.getResponsePrintUrl()));
                }

            }
        } else {
            throw new BusinessException("未找到订单");
        }
        return responseApiModel;
    }

}


